import sqlite3
import os
import typing


class SqliteBase:
    """SQLite数据库基础模块
    
    提供数据库的基础操作，包括数据库文件管理、连接管理
    以及获取数据库基本信息等功能。
    """

    def __init__(self, _db_path: str = 'default.db'):
        """初始化数据库基础模块
        
        Args:
            _db_path: 数据库文件的路径，默认为'default.db'
        """
        self.db_path = _db_path
        self.connection = None
        self.cursor = None
        self.execution_result = None

    def is_database_exists(self) -> bool:
        """判断数据库文件是否存在
        
        Returns:
            bool: 如果文件存在返回True，否则返回False
            
        示例:
            >>> db = SqliteBase('test.db')
            >>> exists = db.is_database_exists()
        """
        result = os.path.exists(self.db_path)
        return result

    def create_database_file(self) -> None:
        """创建数据库文件
        
        如果数据库文件不存在，则创建一个新的数据库文件；
        如果已存在，则提示文件已存在。
        
        示例:
            >>> db = SqliteBase('test.db')
            >>> db.create_database_file()
        """
        if not self.is_database_exists():
            # 创建空的数据库文件
            open(self.db_path, 'a').close()
            print(f"数据库文件 {self.db_path} 创建成功")
        else:
            print(f"数据库文件 {self.db_path} 已存在")

    def connect_database(self) -> bool:
        """连接数据库文件
        
        如果数据库文件存在，则建立连接并创建游标；
        如果文件不存在，则提示无法连接。
        
        Returns:
            bool: 连接成功返回True，否则返回False
            
        示例:
            >>> db = SqliteBase('test.db')
            >>> connected = db.connect_database()
        """
        if self.is_database_exists():
            self.connection = sqlite3.connect(self.db_path)
            self.cursor = self.connection.cursor()
            print("数据库连接成功")
            result = True
        else:
            print("数据库文件不存在，无法连接")
            result = False
        return result

    def execute_command(self, _command: str) -> bool:
        """执行SQL命令
        
        执行指定的SQL命令，并根据命令类型保存执行结果。
        
        Args:
            _command: 字符串类型的SQL命令
            
        Returns:
            bool: 执行成功返回True，否则返回False
            
        示例:
            >>> db = SqliteBase('test.db')
            >>> db.connect_database()
            >>> success = db.execute_command("CREATE TABLE IF NOT EXISTS test (id INTEGER)")
        """
        try:
            if not self.cursor:
                print("请先连接数据库")
                return False
            
            self.cursor.execute(_command)
            self.connection.commit()
            # 如果是查询命令，保存查询结果，否则保存True表示执行成功
            self.execution_result = self.cursor.fetchall() if 'SELECT' in _command.upper() else True
            result = True
        except sqlite3.Error as e:
            print(f"执行命令失败: {e}")
            result = False
        return result

    def get_execution_result(self) -> typing.Any:
        """获取最近一次查询操作的结果
        
        Returns:
            最近一次查询的结果，格式为元组列表
            
        示例:
            >>> db = SqliteBase('test.db')
            >>> db.connect_database()
            >>> db.execute_command("SELECT * FROM test")
            >>> result = db.get_execution_result()
        """
        result = self.execution_result
        return result

    def close_connection(self) -> None:
        """关闭数据库连接
        
        如果存在活跃连接，则关闭连接并重置连接和游标对象。
        
        示例:
            >>> db = SqliteBase('test.db')
            >>> db.connect_database()
            >>> # 执行操作...
            >>> db.close_connection()
        """
        if self.connection:
            self.connection.close()
            self.connection = None
            self.cursor = None
            print("数据库连接已关闭")

    def get_database_info(self) -> dict:
        """获取数据库基本信息
        
        Returns:
            dict: 包含数据库信息的字典
            
        示例:
            >>> db = SqliteBase('test.db')
            >>> db.connect_database()
            >>> info = db.get_database_info()
        """
        info = {
            'database_path': self.db_path,
            'database_exists': self.is_database_exists(),
            'is_connected': self.connection is not None,
            'table_count': 0,
            'tables': []
        }
        
        if self.connection:
            # 获取数据库中的表数量和表名
            self.cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
            tables = self.cursor.fetchall()
            info['table_count'] = len(tables)
            info['tables'] = [table[0] for table in tables]
        
        result = info
        return result

    def get_table_info(self, _table_name: str) -> dict:
        """获取指定表的信息
        
        Args:
            _table_name: 表名
            
        Returns:
            dict: 包含表信息的字典
            
        示例:
            >>> db = SqliteBase('test.db')
            >>> db.connect_database()
            >>> table_info = db.get_table_info('maintable')
        """
        info = {
            'table_name': _table_name,
            'column_count': 0,
            'columns': [],
            'row_count': 0
        }
        
        if self.connection:
            # 获取表的列信息
            self.cursor.execute(f"PRAGMA table_info({_table_name});")
            columns = self.cursor.fetchall()
            info['column_count'] = len(columns)
            info['columns'] = [{'name': col[1], 'type': col[2], 'notnull': col[3], 'default': col[4], 'pk': col[5]} for col in columns]
            
            # 获取表的行数
            try:
                self.cursor.execute(f"SELECT COUNT(*) FROM {_table_name};")
                row_count = self.cursor.fetchone()[0]
                info['row_count'] = row_count
            except sqlite3.Error:
                info['row_count'] = -1  # 表示无法获取行数
        
        result = info
        return result


class SqliteQuery(SqliteBase):
    """SQLite数据库查询模块
    
    提供简化的数据库查询操作功能。
    """

    def quick_connect(self, _db_path: str = 'default.db') -> bool:
        """快速连接到数据库
        
        一站式完成数据库文件检查、创建（如果需要）、连接。
        
        Args:
            _db_path: 数据库文件的路径，默认为'default.db'
            
        Returns:
            bool: 连接成功返回True，否则返回False
            
        示例:
            >>> db = SqliteQuery()
            >>> connected = db.quick_connect('test.db')
        """
        self.db_path = _db_path
        self.create_database_file()
        result = self.connect_database()
        return result

    def query_all(self, _table_name: str = 'maintable') -> typing.List[typing.Tuple]:
        """查询指定表的所有数据
        
        Args:
            _table_name: 要查询的表名，默认为'maintable'
            
        Returns:
            list: 查询结果列表，每项为元组
            
        示例:
            >>> db = SqliteQuery()
            >>> db.quick_connect('test.db')
            >>> all_data = db.query_all('users')
        """
        query_command = f"SELECT * FROM `{_table_name}`"
        self.execute_command(query_command)
        result = self.get_execution_result()
        return result

    def query_one(self, _table_name: str, _condition: str = '') -> typing.Optional[typing.Tuple]:
        """查询符合条件的单条数据
        
        Args:
            _table_name: 表名
            _condition: 查询条件，如 "id = 1"
            
        Returns:
            tuple: 查询结果的单条记录，如果没有结果返回None
            
        示例:
            >>> db = SqliteQuery()
            >>> db.quick_connect('test.db')
            >>> user = db.query_one('users', "id = 1")
        """
        query_command = f"SELECT * FROM `{_table_name}`"
        if _condition:
            query_command += f" WHERE {_condition}"
        query_command += " LIMIT 1"
        
        self.execute_command(query_command)
        result_set = self.get_execution_result()
        result = result_set[0] if result_set else None
        return result

    def query_by_columns(self, _table_name: str, _columns: typing.List[str], _condition: str = '') -> typing.List[typing.Tuple]:
        """查询指定表的指定列数据
        
        Args:
            _table_name: 表名
            _columns: 要查询的列名列表
            _condition: 查询条件，如 "status = 'active'"
            
        Returns:
            list: 查询结果列表
            
        示例:
            >>> db = SqliteQuery()
            >>> db.quick_connect('test.db')
            >>> users = db.query_by_columns('users', ['name', 'email'], "age > 18")
        """
        columns_str = ', '.join([f"`{col}`" for col in _columns])
        query_command = f"SELECT {columns_str} FROM `{_table_name}`"
        
        if _condition:
            query_command += f" WHERE {_condition}"
        
        self.execute_command(query_command)
        result = self.get_execution_result()
        return result

    def query_with_limit(self, _table_name: str, _limit: int, _offset: int = 0) -> typing.List[typing.Tuple]:
        """查询指定数量的数据，支持分页
        
        Args:
            _table_name: 表名
            _limit: 查询的最大记录数
            _offset: 偏移量，默认为0
            
        Returns:
            list: 查询结果列表
            
        示例:
            >>> db = SqliteQuery()
            >>> db.quick_connect('test.db')
            >>> page1 = db.query_with_limit('users', 10)  # 获取前10条
            >>> page2 = db.query_with_limit('users', 10, 10)  # 获取第11-20条
        """
        query_command = f"SELECT * FROM `{_table_name}` LIMIT {_limit} OFFSET {_offset}"
        self.execute_command(query_command)
        result = self.get_execution_result()
        return result

    def search(self, _table_name: str, _search_column: str, _search_text: str) -> typing.List[typing.Tuple]:
        """在指定表的指定列中搜索包含特定文本的数据
        
        Args:
            _table_name: 表名
            _search_column: 要搜索的列名
            _search_text: 搜索文本
            
        Returns:
            list: 符合搜索条件的结果列表
            
        示例:
            >>> db = SqliteQuery()
            >>> db.quick_connect('test.db')
            >>> results = db.search('users', 'name', '张三')
        """
        query_command = f"SELECT * FROM `{_table_name}` WHERE `{_search_column}` LIKE '%{_search_text}%'"
        self.execute_command(query_command)
        result = self.get_execution_result()
        return result


class SqliteInsert(SqliteBase):
    """SQLite数据库插入模块
    
    提供简化的数据库数据插入操作功能。
    """

    def insert_one(self, _table_name: str, _data: dict) -> bool:
        """插入单条数据到指定表
        
        Args:
            _table_name: 表名
            _data: 要插入的数据，字典格式，键为列名，值为数据
            
        Returns:
            bool: 插入成功返回True，否则返回False
            
        示例:
            >>> db = SqliteInsert()
            >>> db.quick_connect('test.db')
            >>> success = db.insert_one('users', {'name': '张三', 'age': 25})
        """
        try:
            # 构建插入SQL语句
            columns = ', '.join([f"`{col}`" for col in _data.keys()])
            placeholders = ', '.join(['?' for _ in _data.values()])
            sql = f"INSERT INTO `{_table_name}` ({columns}) VALUES ({placeholders})"
            
            # 执行插入
            if not self.cursor:
                print("请先连接数据库")
                return False
            
            self.cursor.execute(sql, list(_data.values()))
            self.connection.commit()
            self.execution_result = True
            print(f"成功插入数据到表 {_table_name}")
            result = True
        except sqlite3.Error as e:
            print(f"插入数据失败: {e}")
            result = False
        return result

    def insert_many(self, _table_name: str, _data_list: typing.List[dict]) -> bool:
        """批量插入多条数据到指定表
        
        Args:
            _table_name: 表名
            _data_list: 要插入的数据列表，每项为字典
            
        Returns:
            bool: 插入成功返回True，否则返回False
            
        示例:
            >>> db = SqliteInsert()
            >>> db.quick_connect('test.db')
            >>> users = [{'name': '张三', 'age': 25}, {'name': '李四', 'age': 30}]
            >>> success = db.insert_many('users', users)
        """
        if not _data_list:
            print("没有数据需要插入")
            return True
        
        try:
            # 获取列名（假设所有数据项都有相同的列）
            columns = ', '.join([f"`{col}`" for col in _data_list[0].keys()])
            placeholders = ', '.join(['?' for _ in _data_list[0].values()])
            sql = f"INSERT INTO `{_table_name}` ({columns}) VALUES ({placeholders})"
            
            # 准备数据
            data_values = [list(item.values()) for item in _data_list]
            
            # 执行批量插入
            if not self.cursor:
                print("请先连接数据库")
                return False
            
            self.cursor.executemany(sql, data_values)
            self.connection.commit()
            self.execution_result = True
            print(f"成功批量插入 {len(_data_list)} 条数据到表 {_table_name}")
            result = True
        except sqlite3.Error as e:
            print(f"批量插入数据失败: {e}")
            result = False
        return result

    def create_table(self, _table_name: str, _columns: dict) -> bool:
        """创建数据表
        
        Args:
            _table_name: 表名
            _columns: 列定义字典，键为列名，值为列类型
            
        Returns:
            bool: 创建成功返回True，否则返回False
            
        示例:
            >>> db = SqliteInsert()
            >>> db.quick_connect('test.db')
            >>> columns = {'id': 'INTEGER PRIMARY KEY', 'name': 'TEXT', 'age': 'INTEGER'}
            >>> success = db.create_table('users', columns)
        """
        try:
            # 构建CREATE TABLE语句
            columns_str = ', '.join([f"`{col}` {col_type}" for col, col_type in _columns.items()])
            sql = f"CREATE TABLE IF NOT EXISTS `{_table_name}` ({columns_str})"
            
            # 执行创建表
            if not self.cursor:
                print("请先连接数据库")
                return False
            
            self.cursor.execute(sql)
            self.connection.commit()
            self.execution_result = True
            print(f"成功创建表 {_table_name}")
            result = True
        except sqlite3.Error as e:
            print(f"创建表失败: {e}")
            result = False
        return result


class DatabaseOperations:
    """SQLite数据库操作类（统一入口）
    
    整合基础模块、查询模块和插入模块的功能，提供统一的数据库操作接口。
    使用装饰器将子模块修饰为属性，确保懒加载和共享连接。
    """

    def __init__(self, _db_path: str = 'default.db'):
        """初始化数据库操作类
        
        Args:
            _db_path: 数据库文件的路径，默认为'default.db'
        """
        self.db_path = _db_path
        # 私有属性，用于存储各模块实例
        self._base = None
        self._query = None
        self._insert = None
        # 引用基础模块的连接和游标，确保各模块共享同一连接
        self.connection = None
        self.cursor = None
        
    @property
    def base(self) -> SqliteBase:
        """获取基础模块实例
        
        使用装饰器将基础模块修饰为属性，实现懒加载。
        
        Returns:
            SqliteBase: 基础模块实例
            
        示例:
            >>> db = DatabaseOperations()
            >>> db.base.connect_database()
        """
        if self._base is None:
            self._base = SqliteBase(self.db_path)
            # 更新连接和游标引用
            self.connection = self._base.connection
            self.cursor = self._base.cursor
        return self._base
        
    @property
    def query(self) -> SqliteQuery:
        """获取查询模块实例
        
        使用装饰器将查询模块修饰为属性，实现懒加载。
        
        Returns:
            SqliteQuery: 查询模块实例
            
        示例:
            >>> db = DatabaseOperations()
            >>> db.query.quick_connect()
        """
        if self._query is None:
            self._query = SqliteQuery(self.db_path)
            # 确保共享同一连接
            if self._base is not None:
                self._query.connection = self._base.connection
                self._query.cursor = self._base.cursor
        return self._query
        
    @property
    def insert(self) -> SqliteInsert:
        """获取插入模块实例
        
        使用装饰器将插入模块修饰为属性，实现懒加载。
        
        Returns:
            SqliteInsert: 插入模块实例
            
        示例:
            >>> db = DatabaseOperations()
            >>> db.insert.create_table('users', {'id': 'INTEGER PRIMARY KEY'})
        """
        if self._insert is None:
            self._insert = SqliteInsert(self.db_path)
            # 确保共享同一连接
            if self._base is not None:
                self._insert.connection = self._base.connection
                self._insert.cursor = self._base.cursor
        return self._insert

    def quick_connect(self, _db_path: str = 'default.db', _create_table: bool = True) -> bool:
        """快速连接到数据库
        
        一站式完成数据库文件检查、创建（如果需要）、连接，
        并可选择创建默认表。
        
        Args:
            _db_path: 数据库文件的路径，默认为'default.db'
            _create_table: 是否创建默认表，默认为True
            
        Returns:
            bool: 连接成功返回True，否则返回False
            
        示例:
            >>> db = DatabaseOperations()
            >>> connected = db.quick_connect('test.db')
        """
        self.db_path = _db_path
        
        # 如果模块已初始化，更新其数据库路径
        if hasattr(self, '_base') and self._base is not None:
            self._base.db_path = _db_path
        if hasattr(self, '_query') and self._query is not None:
            self._query.db_path = _db_path
        if hasattr(self, '_insert') and self._insert is not None:
            self._insert.db_path = _db_path
        
        # 快速连接 - 通过属性访问确保模块被初始化
        success = self.base.connect_database()
        
        if success and _create_table:
            # 创建默认表
            self.base.execute_command("""
                CREATE TABLE IF NOT EXISTS maintable 
                (id INTEGER PRIMARY KEY, 
                 key TEXT, 
                 value TEXT, 
                 type TEXT DEFAULT 'none')
            """)
        
        # 更新连接和游标引用
        self.connection = self.base.connection
        self.cursor = self.base.cursor
        
        # 确保所有模块共享同一连接
        if hasattr(self, '_query') and self._query is not None:
            self._query.connection = self.connection
            self._query.cursor = self.cursor
        if hasattr(self, '_insert') and self._insert is not None:
            self._insert.connection = self.connection
            self._insert.cursor = self.cursor
        
        print("快速连接完成")
        result = success
        return result

    def close_connection(self) -> None:
        """关闭数据库连接
        
        关闭所有模块共享的数据库连接。
        
        示例:
            >>> db = DatabaseOperations()
            >>> db.quick_connect('test.db')
            >>> # 执行操作...
            >>> db.close_connection()
        """
        # 通过基础模块关闭连接
        if hasattr(self, '_base') and self._base is not None:
            self._base.close_connection()
        
        # 更新连接和游标引用
        self.connection = None
        self.cursor = None
        
        # 确保所有模块的连接也被重置
        if hasattr(self, '_query') and self._query is not None:
            self._query.connection = None
            self._query.cursor = None
        if hasattr(self, '_insert') and self._insert is not None:
            self._insert.connection = None
            self._insert.cursor = None


# 使用示例
if __name__ == "__main__":
    # 创建数据库操作对象
    db_ops = DatabaseOperations()

    
    
    # 快速连接到数据库
    db_ops.quick_connect('example.db')
    
    # 使用插入模块插入数据
    db_ops.insert.insert_one('maintable', {'key': 'key1', 'value': 'value1'})
    db_ops.insert.insert_one('maintable', {'key': 'key2', 'value': 'value2'})
    
    # 使用查询模块查询数据
    print("\n查询所有数据:")
    all_data = db_ops.query.query_all('maintable')
    for row in all_data:
        print(row)
    
    # 使用基础模块获取数据库信息
    print("\n数据库信息:")
    db_info = db_ops.base.get_database_info()
    print(f"数据库文件: {db_info['database_path']}")
    print(f"表数量: {db_info['table_count']}")
    print(f"表列表: {db_info['tables']}")
    
    # 获取表信息
    print("\n表信息:")
    table_info = db_ops.base.get_table_info('maintable')
    print(f"表名: {table_info['table_name']}")
    print(f"列数量: {table_info['column_count']}")
    print(f"行数量: {table_info['row_count']}")
    print("列信息:")
    for col in table_info['columns']:
        print(f"  {col['name']} ({col['type']}) - {'主键' if col['pk'] else ''}")
    

    # 关闭数据库连接
    db_ops.close_connection()
